package com.iqiyi.pps.epg.core.rpc.stream;

import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.api.model.web.stream.TLiveStream;
import com.iqiyi.pps.epg.api.model.web.stream.TLiveStreamMonitor;
import com.iqiyi.pps.epg.api.model.web.stream.TNetMonitorInfo;
import com.iqiyi.pps.epg.api.server.web.stream.LiveStreamWebService;
import com.iqiyi.pps.epg.core.model.channel.ChannelBase;
import com.iqiyi.pps.epg.core.model.program.ProgramData;
import com.iqiyi.pps.epg.core.model.stream.LiveChannelStream;
import com.iqiyi.pps.epg.core.model.stream.LiveStream;
import com.iqiyi.pps.epg.core.model.stream.LiveStreamMonitor;
import com.iqiyi.pps.epg.core.model.stream.StreamCutterIdData;
import com.iqiyi.pps.epg.core.rpc.qipu.impl.QipuManager;
import com.iqiyi.pps.epg.core.service.channel.ChannelServiceImpl;
import com.iqiyi.pps.epg.core.service.program.ProgramService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamServiceImpl;
import com.iqiyi.pps.epg.core.service.stream.LiveStreamService;
import com.iqiyi.pps.epg.core.service.stream.LiveStreamServiceImpl;
import com.iqiyi.pps.epg.core.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2014/12/18.
 */
@Component
public class LiveStreamWebServiceImpl implements LiveStreamWebService.Iface {

    private static Logger logger = LoggerFactory.getLogger(LiveStreamWebServiceImpl.class);

    @Override
    public String createTs(long fatherId, String streamName, String streamIp) throws TException {
        logger.info("[LiveStreamWebServiceImpl][createTs][Params:fatherId={},streamName={},streamIp={}]", new Object[]{fatherId, streamName, streamIp});
        String code = null;
        int sliceDelay = 0;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName) || StringUtils.isEmpty(streamIp)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream _liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            if (_liveStream != null) {  //扩展流数据已存在
                code = Constants.CODE_ERROR_STREAMNAME_EXIST;
                return code;
            }
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream _liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            if (_liveChannelStream == null) {     //频道码流数据不存在
                code = Constants.CODE_ERROR_LIVECHANNELSTREAM_NOT_EXIST;
                return code;
            } else {
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                ChannelBase channelBase = channelService.getChannelBase(fatherId);
                if (channelBase.getLiveType() != 2) {   //不为临时直播
                    if (_liveChannelStream.getStatus() != _liveChannelStream.STATUS_ACTIVED) {
                        code = Constants.CODE_WARNING_LIVECHANNELSTREAM_STATUS;
                        return code;
                    }
                    if (!streamIp.equals(_liveChannelStream.getStreamIp())) {    //用户输入的直播流RTMP源地址与数据库中的数据不匹配
                        code = Constants.CODE_ERROR_STREAMIP_NOT_EQUALS;
                        return code;
                    }
                } else {
                    sliceDelay = channelBase.getSliceDelay();
                }
            }

            // 创建TS流
            JSONObject jsonObject = LiveStreamManager.createTs(streamIp, streamName, _liveChannelStream.getCutterIdTs() + "", sliceDelay, _liveChannelStream.getStreamApiVersion(),
                    _liveChannelStream.getStreamUrls());
            String url = null;
            if (jsonObject != null && ("1".equals(jsonObject.getString("status")) || ApiHttpRequestUtil.MESSAGE_CHANNEL_EXISTS.equals(jsonObject.getString("message")))) {          //HTTP返回成功
                JSONObject data = jsonObject.getJSONObject("data");
                url = data.getString("ch");
            } else {        //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }

            LiveStream liveStream = new LiveStream();
            liveStream.setFatherId(fatherId);
            liveStream.setStreamName(streamName);
            liveStream.setIsDefault(false);
            liveStream.setUuid(UUID.randomUUID().toString());
            liveStream.setUrl(url);
            liveStream.setFormatType(LiveStream.FORMATTYPE_TS);
            liveStream.setStatus(0);
            LiveStream liveStreamMp4 = liveStream.copyNewInstance();
            liveStreamMp4.setUuid(UUID.randomUUID().toString());
            liveStreamMp4.setFormatType(LiveStream.FORMATTYPE_MP4);
            liveStreamService.save(liveStream);
            liveStreamService.save(liveStreamMp4);
            code = Constants.CODE_SUC;
            return code;
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][createTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String startTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][startTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            LiveStream liveStreamMp4 = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_MP4);

            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl())) {       //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 启动Ts流
                JSONObject jsonObject = LiveStreamManager.startTs(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {           //HTTP返回成功
                    // 修改数据
                    liveStream.setStatus(LiveStream.STATUS_START);
                    liveStreamMp4.setStatus(LiveStream.STATUS_START);
                    liveStreamService.edit(liveStream);
                    liveStreamService.edit(liveStreamMp4);

                    if (liveChannelStream.getIsEnable()) {
                        // 写奇普
                        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                        Long qipuId = channelService.getQipuId(fatherId);
                        //     Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0) {
                            // if (qipuId > 0 && oldQipuId > 0) {           // 奇普ID存在
                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                            qipuManager.addLiveStreamToQipu(qipuId, liveStream);
                            qipuManager.addLiveStreamToQipu(qipuId, liveStreamMp4);

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性isSync
                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
                            channelBase.setIsSync(1);
                            channelService.saveBase(channelBase);

                            code = Constants.CODE_SUC;
                            return code;
                        } else {                   //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        // 不写奇普
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {        //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {        //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][startTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String stopTs(long fatherId, String streamName, boolean isQipuOperating) throws TException {
        logger.info("[LiveStreamWebServiceImpl][stopTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            LiveStream liveStreamMp4 = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_MP4);

            // 直播流未启动，无法停止
            if (null == liveStream || liveStream.getStatus() == 0 || liveStream.getStatus() == 2) {
                code = Constants.CODE_ERROR_STREAM_STATUS_STOP;
                return code;
            }

            // 检查频道当前是否有节目正在直播
            if (!checkNotHavingCurrentProgram(fatherId)) {
                code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
                return code;
            }

            if (StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 停止Ts流
                JSONObject jsonObject = LiveStreamManager.stopTs(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {       //HTTP返回成功
                    // 修改数据
                    liveStream.setStatus(LiveStream.STATUS_STOP);
                    liveStreamMp4.setStatus(LiveStream.STATUS_STOP);
                    liveStreamService.edit(liveStream);
                    liveStreamService.edit(liveStreamMp4);

                    if (liveChannelStream.getIsEnable() && isQipuOperating) {
                        // 写奇普
                        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                        Long qipuId = channelService.getQipuId(fatherId);
                        //  Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0) {
                            //   if (qipuId > 0 && oldQipuId > 0) {       //奇普ID存在
//                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStreamMp4.getUuid());

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性isSync
                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
                            channelBase.setIsSync(1);
                            channelService.saveBase(channelBase);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {            //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        // 不写奇普
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {        //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][stopTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String deleteTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][deleteTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            LiveStream liveStreamMp4 = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_MP4);

            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空

                // 检查频道当前是否有节目正在直播
//                if (!checkNotHavingCurrentProgram(fatherId)) {
//                    code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
//                    return code;
//                }

                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
                // 删除Ts流
                JSONObject jsonObject = LiveStreamManager.deleteTs(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {           //HTTP返回成功
                    // 删除数据
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_TS);
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_MP4);

                    // 写奇普
                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    Long qipuId = channelService.getQipuId(fatherId);
                    //   Long oldQipuId = channelService.getOldQipuId(fatherId);
                    if (qipuId > 0) {
                        //  if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                        qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
                        qipuManager.delLiveStreamToQipu(qipuId, liveStreamMp4.getUuid());

                        //老奇普
//                        LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
//                        List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(fatherId, true);
//                        liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                        //设置频道属性isSync
                        ChannelBase channelBase = channelService.getChannelBase(fatherId);
                        channelBase.setIsSync(1);
                        channelService.saveBase(channelBase);
                        code = Constants.CODE_SUC;
                        return code;
                    } else {        //奇普ID不存在
                        code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                        return code;
                    }

                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][deleteTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }


    @Override
    public List<TLiveStream> getLiveStream(long fatherId, String streamName, String formatType) throws TException {
        LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
        List<LiveStream> liveStreams = null;
        if (formatType == null) {
            liveStreams = liveStreamService.get(fatherId, streamName);
        } else if (null == streamName) {
            liveStreams = liveStreamService.getByFormatType(fatherId, formatType);
        } else {
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, formatType);
            if (liveStream != null) {
                liveStreams = new ArrayList<LiveStream>();
                liveStreams.add(liveStream);
            }
        }

        List<TLiveStream> tLiveStreams = new ArrayList<TLiveStream>();
        if (liveStreams != null) {
            for (LiveStream liveStream : liveStreams) {
                tLiveStreams.add(liveStream.toThriftEntity());
            }
        }
        return tLiveStreams;
    }

    @Override
    public String createFlv(long fatherId, String streamName, String isDefault, String streamIp) throws TException {
        logger.info("[LiveStreamWebServiceImpl][createFlv][Params:fatherId={},streamName={},isDefault={},streamIp={}]", new Object[]{fatherId, streamName, isDefault, streamIp});
        String code = null;
        int sliceDelay = 0;
        int userCount = 0;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName) || StringUtils.isEmpty(streamIp)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }

            LiveStream liveStream = new LiveStream();
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream _liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
            if (_liveStream != null) {  //扩展流数据已存在
                code = Constants.CODE_ERROR_STREAMNAME_EXIST;
                return code;
            }
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream _liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            if (_liveChannelStream == null) {     //频道码流数据不存在
                code = Constants.CODE_ERROR_LIVECHANNELSTREAM_NOT_EXIST;
                return code;
            } else {
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                ChannelBase channelBase = channelService.getChannelBase(fatherId);
                if (channelBase.getLiveType() != 2) {   //不为临时直播
                    if (_liveChannelStream.getStatus() != _liveChannelStream.STATUS_ACTIVED) {
                        code = Constants.CODE_WARNING_LIVECHANNELSTREAM_STATUS;
                        return code;
                    }
                    if (!streamIp.equals(_liveChannelStream.getStreamIp())) {    //用户输入的直播流FMS源地址与数据库中的数据不匹配
                        code = Constants.CODE_ERROR_STREAMIP_NOT_EQUALS;
                        return code;
                    }
                } else {
                    sliceDelay = channelBase.getSliceDelay();
                }
                userCount = channelBase.getUserCount();
            }
            //将已有flv流的默认值设置为false
//            if ("1".equals(isDefault)) {
//                LiveStream _defaultLiveStream = liveStreamService.getByDefault(fatherId, LiveStream.FORMATTYPE_FLV, true);
//                if (_defaultLiveStream != null) {
//                    _defaultLiveStream.setIsDefault(false);
//                    liveStreamService.edit(_defaultLiveStream);
//                }
//            }
            // 创建Flv流
            JSONObject jsonObject = LiveStreamManager.createFlv(streamIp, streamName, _liveChannelStream.getPeerCount() + "",
                    _liveChannelStream.getBcsNum() + "", _liveChannelStream.getCutterIdFlv() + "", sliceDelay, userCount,
                    LiveChannelStream.STREAM_TYPE_RESOLUTION_MAP.get(_liveChannelStream.getStreamType()), _liveChannelStream.getStreamApiVersion(),
                    _liveChannelStream.getStreamUrls(),_liveChannelStream.getPlayType());
            if (jsonObject != null &&
                    ("1".equals(jsonObject.getString("status")) || ApiHttpRequestUtil.MESSAGE_CHANNEL_EXISTS.equals(jsonObject.getString("message")))) {  //HTTP返回成功
                JSONObject data = jsonObject.getJSONObject("data");
                String url = data.getString("ch");
                String ppstream = data.getString("ppstream");
                int delayS = data.getIntValue("delay_s");
                int delayE = data.getIntValue("delay_e");
                String hcdnlive = data.getString("hcdnlive");

                liveStream.setFatherId(fatherId);
                liveStream.setStreamName(streamName);
                if ("1".equals(isDefault))
                    liveStream.setIsDefault(true);
                if ("0".equals(isDefault))
                    liveStream.setIsDefault(false);
                liveStream.setUuid(UUID.randomUUID().toString());
                liveStream.setUrl(url);
                liveStream.setSliceDelay(sliceDelay);
                liveStream.setDelayS(delayS);
                liveStream.setDelayE(delayE);
                liveStream.setFormatType(LiveStream.FORMATTYPE_FLV);
                liveStream.setStatus(0);
                LiveStream liveStreamHcdn = liveStream.copyNewInstance();
                liveStreamHcdn.setUuid(UUID.randomUUID().toString());
                liveStreamHcdn.setFormatType(LiveStream.FORMATTYPE_HCDN);
                liveStreamHcdn.setUrl(ppstream);
                liveStreamHcdn.setIsDefault(false);

                if (null != hcdnlive) {
                    LiveStream liveStreamHlflv = liveStream.copyNewInstance();
                    liveStreamHlflv.setUuid(UUID.randomUUID().toString());
                    liveStreamHlflv.setFormatType(LiveStream.FORMATTYPE_HLFLV);
                    liveStreamHlflv.setUrl(hcdnlive);
                    liveStreamHlflv.setIsDefault(false);
                    liveStreamService.save(liveStreamHlflv);
                }

                liveStreamService.save(liveStream);
                liveStreamService.save(liveStreamHcdn);
                code = Constants.CODE_SUC;
                return code;
            } else {        //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][createFlv][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String startFlv(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][startFlv][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
            LiveStream liveStreamHcdn = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HCDN);
            LiveStream liveStreamHcdnlive = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HLFLV);
            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 启动Flv流
                JSONObject jsonObject = LiveStreamManager.startFlv(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {         //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_START);
                    liveStreamHcdn.setStatus(LiveStream.STATUS_START);
                    liveStreamService.edit(liveStream);
                    liveStreamService.edit(liveStreamHcdn);

                    if (null != liveStreamHcdnlive) {
                        liveStreamHcdnlive.setStatus(LiveStream.STATUS_START);
                        liveStreamService.edit(liveStreamHcdnlive);
                    }

                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    if (liveChannelStream.getIsEnable()) {
                        // 写奇普
                        Long qipuId = channelService.getQipuId(fatherId);
                        //  Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0) {
                            //  if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                            // FLV流不为默认时，如果有其他默认FLV流则不写入奇普

//                            if (!liveStream.getIsDefault()) {
//                                LiveStream _liveStreamDefault = liveStreamService.getByDefault(fatherId, LiveStream.FORMATTYPE_FLV, true);
//                                if (_liveStreamDefault != null) { //不存在默认的FLV流，入奇普
//                                    qipuManager.setDefaultLiveStreamToQipu(qipuId, _liveStreamDefault);
//                                    logger.info("[LiveStreamWebServiceImpl][startFlv][setDefaultLiveStreamToQipu][finish]{}", JSON.toJSONString(_liveStreamDefault));
//                                } else {
//                                    logger.info("[LiveStreamWebServiceImpl][startFlv][_liveStreamDefault == null]");
//                                    qipuManager.setDefaultLiveStreamToQipu(qipuId, liveStream);
//                                    liveStream.setIsDefault(true);
//                                    liveStreamService.save(liveStream);
//                                    logger.info("[LiveStreamWebServiceImpl][startFlv][setDefaultLiveStreamToQipu][finish]{}", JSON.toJSONString(liveStream));
//                                }
//                            } else {
//                                qipuManager.setDefaultLiveStreamToQipu(qipuId, liveStream);
//                            }
                            qipuManager.addLiveStreamToQipu(qipuId, liveStream);
                            qipuManager.addLiveStreamToQipu(qipuId, liveStreamHcdn);
                            if (null != liveStreamHcdnlive) {
                                qipuManager.addLiveStreamToQipu(qipuId, liveStreamHcdnlive);
                            }

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性hasStream\isSync
//                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
//                            channelBase.setHasStream(1);
//                            channelBase.setIsSync(1);
//                            channelService.saveBase(channelBase);
                            channelService.sqlNotifyHasStream(fatherId);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {        //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        channelService.sqlNotifyHasStream(fatherId);
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][startFlv][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String stopFlv(long fatherId, String streamName, boolean isQipuOperating) throws TException {
        logger.info("[LiveStreamWebServiceImpl][stopFlv][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
            LiveStream liveStreamHcdn = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HCDN);
            LiveStream liveStreamHcdnlive = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HLFLV);

            // 直播流未启动，无法停止
            if (null == liveStream || liveStream.getStatus() == 0 || liveStream.getStatus() == 2) {
                code = Constants.CODE_ERROR_STREAM_STATUS_STOP;
                return code;
            }

            // 检查频道当前是否有节目正在直播
            if (!checkNotHavingCurrentProgram(fatherId)) {
                code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
                return code;
            }

            if (StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
                // 停止Flv流
                JSONObject jsonObject = LiveStreamManager.stopFlv(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_STOP);
                    liveStreamHcdn.setStatus(LiveStream.STATUS_STOP);
                    liveStreamService.edit(liveStream);
                    liveStreamService.edit(liveStreamHcdn);

                    if (null != liveStreamHcdnlive) {
                        liveStreamHcdnlive.setStatus(LiveStream.STATUS_STOP);
                        liveStreamService.edit(liveStreamHcdnlive);
                    }

                    if (liveChannelStream.getIsEnable() && isQipuOperating) {
                        // 写奇普
                        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                        Long qipuId = channelService.getQipuId(fatherId);
                        //        Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0) {
                            //        if (qipuId > 0 && oldQipuId > 0) {       //奇普ID存在
//                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStreamHcdn.getUuid());

                            //频道FLV流为默认时，删除DefaultLiveStream
//                            if (liveStream.getIsDefault()) {
//                                qipuManager.setDefaultLiveStreamToQipu(qipuId, null);
//                            }

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性isSync
                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
                            channelBase.setIsSync(1);
                            channelService.saveBase(channelBase);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {                //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        // 不写奇普
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {                    //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                        //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][stopFlv][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String deleteFlv(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][deleteFlv][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
            LiveStream liveStreamHcdn = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HCDN);
            LiveStream liveStreamHcdnlive = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_HLFLV);
            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 检查频道当前是否有节目正在直播
//                if (!checkNotHavingCurrentProgram(fatherId)) {
//                    code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
//                    return code;
//                }

                // 停止Flv流
                JSONObject jsonObject = LiveStreamManager.deleteFlv(liveStream.getUrl(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    // 删除数据
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_HCDN);
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_HLFLV);

                    // 删奇普
                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    Long qipuId = channelService.getQipuId(fatherId);
                    // Long oldQipuId = channelService.getOldQipuId(fatherId);
                    if (qipuId > 0) {
                        // if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                        qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
                        qipuManager.delLiveStreamToQipu(qipuId, liveStreamHcdn.getUuid());
                        if (null != liveStreamHcdnlive) {
                            qipuManager.delLiveStreamToQipu(qipuId, liveStreamHcdnlive.getUuid());
                        }
                        //频道FLV流未默认时，删除默认,如果有其他FLV则设置为默认
                        if (liveStream.getIsDefault()) {
                            ChannelStreamWebServiceImpl channelStreamWebService = (ChannelStreamWebServiceImpl) ApplicationContextUtil.getBean(ChannelStreamWebServiceImpl.class);
                            TLiveStream defaultStream = channelStreamWebService.getDefaultFLVStreamByName(liveStream.getFatherId(), liveStream.getStreamName());
                            qipuManager.setDefaultLiveStreamToQipu(qipuId, transferLiveStream(defaultStream));
                        }

                        //老奇普
//                        LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
//                        List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(fatherId, true);
//                        liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                        //设置频道属性isSync
                        ChannelBase channelBase = channelService.getChannelBase(fatherId);
                        channelBase.setIsSync(1);
                        channelService.saveBase(channelBase);
                        code = Constants.CODE_SUC;
                        return code;
                    } else {        //奇普ID不存在
                        code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                        return code;
                    }

                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][deleteFlv][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String p2pOnline(long fatherId, String streamName, String streamIp) throws TException {
        logger.info("[LiveStreamWebServiceImpl][p2pOnline][Params:fatherId={},streamName={},streamIp={}]", new Object[]{fatherId, streamName, streamIp});
        String code = null;
        // Logger Time
        Long p2pOnlineStart = System.currentTimeMillis();
        logger.info("[LiveStreamWebServiceImpl][p2pOnline][start:{}]", DateUtils.defDateFormat(new Date(p2pOnlineStart)));
        try {
            if (fatherId <= 0 || StringUtils.isEmpty(streamName) || StringUtils.isEmpty(streamIp)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            // Logger Time
            Long getP2PStart = System.currentTimeMillis();

            LiveStream liveStream = new LiveStream();
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream _liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_P2P);
            logger.info("[LiveStreamWebServiceImpl][p2pOnline][GetP2P][***Time:{}***]", (System.currentTimeMillis() - getP2PStart));
            if (_liveStream != null) {      //流已存在
                code = Constants.CODE_ERROR_STREAMNAME_EXIST;
                return code;
            }
            // Logger Time
            Long getLiveChannelStart = System.currentTimeMillis();
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            logger.info("[LiveStreamWebServiceImpl][p2pOnline][GetLiveChannel][***Time:{}***]", (System.currentTimeMillis() - getLiveChannelStart));
            if (liveChannelStream == null) {     //频道码流数据不存在
                code = Constants.CODE_ERROR_LIVECHANNELSTREAM_NOT_EXIST;
                return code;
            } else { // 未编码
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                ChannelBase channelBase = channelService.getChannelBase(fatherId);
                if (channelBase.getLiveType() != 2) {   //不为临时直播
                    if (liveChannelStream.getStatus() != liveChannelStream.STATUS_ACTIVED) {
                        code = Constants.CODE_WARNING_LIVECHANNELSTREAM_STATUS;
                        return code;
                    }
                    if (!streamIp.equals(liveChannelStream.getStreamIp())) {    //用户输入的直播流FMS源地址与数据库中的数据不匹配
                        code = Constants.CODE_ERROR_STREAMIP_NOT_EQUALS;
                        return code;
                    }
                }
            }

            // Logger Time
            Long httpStart = System.currentTimeMillis();
            // p2p流上线
            JSONObject jsonObject = LiveStreamManager.p2pOnline(streamIp, liveChannelStream.getId() + "", streamName, liveChannelStream.getPeerCount() + "");
            logger.info("[LiveStreamWebServiceImpl][p2pOnline][HttpStart][***Time:{}***]", (System.currentTimeMillis() - httpStart));
            if (jsonObject != null && jsonObject.getJSONObject("content").getInteger("code") == 0) {    //HTTP返回成功
                String url = jsonObject.getJSONObject("content").getString("url");
                liveStream.setFatherId(fatherId);
                liveStream.setStreamName(streamName);
                liveStream.setIsDefault(false);
                liveStream.setUuid(UUID.randomUUID().toString());
                liveStream.setUrl(url);
                liveStream.setFormatType(LiveStream.FORMATTYPE_P2P);
                liveStream.setStatus(1);
                liveStreamService.save(liveStream);

                if (liveChannelStream.getIsEnable()) {
                    // 写奇普
                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    Long qipuId = channelService.getQipuId(fatherId);
//                    Long oldQipuId = channelService.getOldQipuId(fatherId);
                    if (qipuId > 0) {
                        //if (qipuId > 0 && oldQipuId > 0) {    //奇普ID存在
                        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                        // Logger Time
                        Long writerNewQipuStart = System.currentTimeMillis();
                        qipuManager.addLiveStreamToQipu(qipuId, liveStream);
                        logger.info("[LiveStreamWebServiceImpl][p2pOnline][WriterNewQipuStart][***Time:{}***]", (System.currentTimeMillis() - writerNewQipuStart));

                        // Logger Time
//                        Long writerOldQipuStart = System.currentTimeMillis();
                        //老奇普
//                        List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                        liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);
//                        logger.info("[LiveStreamWebServiceImpl][p2pOnline][WriterOldQipuStart][***Time:{}***]", (System.currentTimeMillis() - writerOldQipuStart));

                        //设置频道属性isSync
                        ChannelBase channelBase = channelService.getChannelBase(fatherId);
                        channelBase.setIsSync(1);
                        channelService.saveBase(channelBase);
                        code = Constants.CODE_SUC;
                        return code;
                    } else {             //奇普ID不存在
                        code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                        return code;
                    }
                } else {
                    // 不写奇普
                    code = Constants.CODE_SUC;
                    return code;
                }
            } else {                //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            Long p2pOnlineEnd = System.currentTimeMillis();
            logger.info("[LiveStreamWebServiceImpl][p2pOnline][End:{}][***Time:{}***]", DateUtils.defDateFormat(new Date(p2pOnlineEnd)), (p2pOnlineEnd - p2pOnlineStart));
            logger.info("[LiveStreamWebServiceImpl][p2pOnline][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String p2pOffline(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][p2pOffline][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        // Logger Time
        Long p2pOfflineStart = System.currentTimeMillis();
        logger.info("[LiveStreamWebServiceImpl][p2pOffline][start:{}]", DateUtils.defDateFormat(new Date(p2pOfflineStart)));
        try {
            if (fatherId <= 0 || org.apache.commons.lang.StringUtils.isEmpty(streamName)) {
                return Constants.CODE_ERROR_PARAM;
            }
            // Logger Time
            Long getP2PStart = System.currentTimeMillis();

            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_P2P);
            logger.info("[LiveStreamWebServiceImpl][p2pOffline][GetP2P][***Time:{}***]", (System.currentTimeMillis() - getP2PStart));
            if (liveStream == null) {         //流数据不存在
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }

            // 直播流未启动，无法停止
            if (liveStream.getStatus() == 0 || liveStream.getStatus() == 2) {
                code = Constants.CODE_ERROR_STREAM_STATUS_STOP;
                return code;
            }

            // Logger Time
            Long getLiveChannelStart = System.currentTimeMillis();
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            logger.info("[LiveStreamWebServiceImpl][p2pOffline][GetLiveChannel][***Time:{}***]", (System.currentTimeMillis() - getLiveChannelStart));

            // Logger Time
            Long httpStart = System.currentTimeMillis();
            // p2p流下线
            JSONObject jsonObject = LiveStreamManager.p2pOffline(liveChannelStream.getId() + "");
            logger.info("[LiveStreamWebServiceImpl][p2pOffline][HttpStart][***Time:{}***]", (System.currentTimeMillis() - httpStart));

            if ((jsonObject != null && jsonObject.getJSONObject("content").getInteger("code") == 0)
                    || (jsonObject != null && jsonObject.getJSONObject("content").getInteger("code") == 1 && LiveStreamManager.P2P_OFFLINE_REPEAT.equals(jsonObject.getJSONObject("content").getString("error_reason")))) {   //HTTP返回成功
                // 删除数据
                liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_P2P);

                // 删奇普
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                Long qipuId = channelService.getQipuId(fatherId);
                // Long oldQipuId = channelService.getOldQipuId(fatherId);
                if (qipuId > 0) {
                    //  if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                    QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                    // Logger Time
                    Long writerNewQipuStart = System.currentTimeMillis();
                    // 新奇普
                    qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
                    logger.info("[LiveStreamWebServiceImpl][p2pOffline][WriterNewQipuStart][***Time:{}***]", (System.currentTimeMillis() - writerNewQipuStart));

                    // Logger Time
//                    Long writerOldQipuStart = System.currentTimeMillis();
                    //老奇普
//                    List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(fatherId, true);
//                    liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);
//                    logger.info("[LiveStreamWebServiceImpl][p2pOffline][WriterOldQipuStart][***Time:{}***]", (System.currentTimeMillis() - writerOldQipuStart));

                    //设置频道属性isSync
                    ChannelBase channelBase = channelService.getChannelBase(fatherId);
                    channelBase.setIsSync(1);
                    channelService.saveBase(channelBase);
                    code = Constants.CODE_SUC;
                    return code;
                } else {                    //奇普ID不存在
                    code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                    return code;
                }
            } else {  //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            Long p2pOfflineEnd = System.currentTimeMillis();
            logger.info("[LiveStreamWebServiceImpl][p2pOffline][End:{}][***Time:{}***]", DateUtils.defDateFormat(new Date(p2pOfflineEnd)), (p2pOfflineEnd - p2pOfflineStart));
            logger.info("[LiveStreamWebServiceImpl][p2pOffline][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    private LiveStream transferLiveStream(TLiveStream liveStream) {
        if (null == liveStream) {
            return null;
        }

        LiveStream result = new LiveStream();

        result.setId(liveStream.getId());
        result.setFatherId(liveStream.getFatherId());
        result.setStreamName(liveStream.getStreamName());
        result.setIsDefault(!"0".equals(liveStream.getIsDefault()));
        result.setUuid(liveStream.getUuid());
        result.setUrl(liveStream.getUrl());
        result.setFormatType(liveStream.getFormatType());
        result.setStatus(liveStream.getStatus());
        result.setAddTime(null != liveStream.getAddTime() ? new Timestamp(Long.parseLong(liveStream.getAddTime())) : null);
        result.setUpdateTime(null != liveStream.getUpdateTime() ? new Timestamp(Long.parseLong(liveStream.getAddTime())) : null);

        return result;
    }

    @Override
    public List<Map<String, String>> getCutterIdInfo(int maxVal, String sortType, String cutterType) throws TException {
        logger.info("[LiveStreamWebServiceImpl][getCutterIdInfo][maxVal={}][sortType={}][cutterType={}]", maxVal, sortType, cutterType);
        try {
            List<Map<String, String>> result = new ArrayList<>();
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            List<StreamCutterIdData> cutterIdDataList = service.getCutterIdInfo(maxVal, sortType, cutterType);
            if (null == cutterIdDataList || cutterIdDataList.size() == 0) {
                return null;
            }

            for (StreamCutterIdData item : cutterIdDataList) {
                Map<String, String> temp = new HashMap();
                temp.put("cutterId", item.getCutterId());
                temp.put("desc", item.getDesc());
                temp.put("count", item.getCount());
                result.add(temp);
            }
            return result;
        } catch (Exception e) {
            logger.info("[LiveStreamWebServiceImpl][getCutterIdInfo][exception={}]", e);
            return null;
        }
    }

    private boolean checkNotHavingCurrentProgram(long fatherId) {
        logger.info("[LiveStreamWebServiceImpl][checkHavingCurrentProgram][fatherId={}]", fatherId);

        try {
            ProgramService service = (ProgramService) ApplicationContextUtil.getBean(ProgramService.class);
            List<ProgramData> currentPrograms = service.getCurrentProgram(Long.valueOf(fatherId).intValue());

            if ((null != currentPrograms) && (currentPrograms.size() > 0)) {
                logger.info("[LiveStreamWebServiceImpl][checkHavingCurrentProgram][currentProgramsSize={}]", currentPrograms.size());
                return false;
            }

            logger.info("[LiveStreamWebServiceImpl][checkHavingCurrentProgram][fatherId={}][currentPrograms={}]", fatherId,
                    null == currentPrograms ? null : currentPrograms.size());

            return true;
        } catch (Exception e) {
            logger.error("[LiveStreamWebServiceImpl][checkHavingCurrentProgram][exception={}]", e);
            return false;
        }

    }

    @Override
    public String restartFlv(long fatherId, String streamName, String internalIp, String streamIp) {
        logger.info("[LiveStreamWebServiceImpl][restartFlv][fatherId={}][streamName={}][internalIp={}][streamIp={}]",
                fatherId, streamName, internalIp, streamIp);
        try {
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = service.get(fatherId, streamName, LiveStream.FORMATTYPE_FLV);
            LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

            JSONObject flvResult = LiveStreamManager.restartFlv(liveStream.getUrl(), internalIp, streamName, liveChannelStream.getStreamApiVersion(),
                    liveChannelStream.getStreamUrls());
            if (null != flvResult && "1".equals(flvResult.getString("status"))) {
                return Constants.CODE_SUC;
            } else {
                return Constants.CODE_ERROR;
            }
        } catch (Exception e) {
            logger.info("[LiveStreamWebServiceImpl][restartFlv][fatherId=" + fatherId + "][streamName=" + streamName + "][exception={}]", e);
            return Constants.CODE_ERROR;
        }
    }

    @Override
    public String restartTs(long fatherId, String streamName, String internalIp, String streamIp) {
        logger.info("[LiveStreamWebServiceImpl][restartTs][fatherId={}][streamName={}][internalIp={}][streamIp={}]",
                fatherId, streamName, internalIp, streamIp);
        try {
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = service.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

            JSONObject tsResult = LiveStreamManager.restartTs(liveStream.getUrl(), internalIp, streamName, liveChannelStream.getStreamApiVersion(),
                    liveChannelStream.getStreamUrls());
            if (null != tsResult && "1".equals(tsResult.getString("status"))) {
                return Constants.CODE_SUC;
            } else {
                return Constants.CODE_ERROR;
            }
        } catch (Exception e) {
            logger.info("[LiveStreamWebServiceImpl][restartTs][fatherId=" + fatherId + "][streamName=" + streamName + "][exception={}]", e);
            return Constants.CODE_ERROR;
        }
    }

    @Override
    public List getNetMonitorInfo(long channelQipuId) {
        List<TNetMonitorInfo> monitorInfos = new ArrayList<>();
        try {
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            return service.getNetMonitorInfo(channelQipuId);
        } catch (Exception e) {
            logger.error("[getNetMonitorInfo][exception={}]", e);
            return monitorInfos;
        }
    }

    @Override
    public String saveLiveStreamMonitor(TLiveStreamMonitor tLiveStreamMonitor) {

        final LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
        try {
            List<String> errorCodes = service.getNotifyErrCode();

            final LiveStreamMonitor liveStreamMonitor = new LiveStreamMonitor();
            liveStreamMonitor.setSrcId(tLiveStreamMonitor.getSrcId());
            liveStreamMonitor.setSrcDesc(tLiveStreamMonitor.getSrcDesc());
            liveStreamMonitor.setMsgId(tLiveStreamMonitor.getMsgId());
            liveStreamMonitor.setMsgDesc(tLiveStreamMonitor.getMsgDesc());
            liveStreamMonitor.setProgName(tLiveStreamMonitor.getProgName());
            liveStreamMonitor.setProgNum(tLiveStreamMonitor.getProgNum());
            liveStreamMonitor.setClientHost(tLiveStreamMonitor.getClientHost());
            //time 传来的中间空格多了，无法直接用Timestamp.valueOf
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = format.parse(tLiveStreamMonitor.getTime());
            liveStreamMonitor.setTime(new Timestamp(date.getTime()));

            liveStreamMonitor.setAddTime(new Timestamp(System.currentTimeMillis()));
            service.saveStreamMonitorLog(liveStreamMonitor);

            if(errorCodes.indexOf(liveStreamMonitor.getMsgId()+"")!=-1){
                Thread thread = new Thread(){
                    @Override
                    public void run() {
                        String head = "【信号监控报警】 ";
                        String tt = liveStreamMonitor.getTime().toString();
                        String msg = head + "服务器IP:" +liveStreamMonitor.getClientHost()+ "; 节目持久ID:"+liveStreamMonitor.getSrcId() + "; 频道名称:" + liveStreamMonitor.getProgName()+"; " +
                                "UDP地址:" + liveStreamMonitor.getSrcDesc()+"; 错误信息:"+liveStreamMonitor.getMsgDesc()+"; Time:"+tt.substring(0,tt.length()-2);
                        service.emailNotifyUser(msg);
                    }
                };
                thread.start();
            }
            return Constants.CODE_SUC;
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_FAIL;
        }
    }

    @Override
    public String createDolby(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][createDolby][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        int sliceDelay = 0;
        int userCount = 0;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream _liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);
            if (_liveStream != null) {  //扩展流数据已存在
                code = Constants.CODE_ERROR_STREAMNAME_EXIST;
                return code;
            }
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream _liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            if (_liveChannelStream == null) {     //频道码流数据不存在
                code = Constants.CODE_ERROR_LIVECHANNELSTREAM_NOT_EXIST;
                return code;
            } else {
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                ChannelBase channelBase = channelService.getChannelBase(fatherId);
                if (channelBase.getLiveType() != 2) {   //不为临时直播
                    if (_liveChannelStream.getStatus() != _liveChannelStream.STATUS_ACTIVED) {
                        code = Constants.CODE_WARNING_LIVECHANNELSTREAM_STATUS;
                        return code;
                    }
                    // TODO: 检测杜比stream_url是否与数据库一致
//                    if (!streamIp.equals(_liveChannelStream.getStreamIp())) {    //用户输入的直播流RTMP源地址与数据库中的数据不匹配
//                        code = Constants.CODE_ERROR_STREAMIP_NOT_EQUALS;
//                        return code;
//                    }
                } else {
                    sliceDelay = channelBase.getSliceDelay();
                }
                userCount = channelBase.getUserCount();
            }

            // 创建TS流
            JSONObject jsonObject = LiveStreamManager.createDolby(_liveChannelStream.getDolbyStreamUrl(), _liveChannelStream.getDolbyStreamName(),
                    _liveChannelStream.getCutterIdTs() + "", sliceDelay, userCount,
                    LiveChannelStream.STREAM_TYPE_RESOLUTION_MAP.get(_liveChannelStream.getStreamType()), _liveChannelStream.getStreamApiVersion(),
                    _liveChannelStream.getDolbyStreamUrls());
            String url = null;
            int delayS = 0;
            int delayE = 0;
            String dolby_ch = "";
            if (jsonObject != null && ("1".equals(jsonObject.getString("status")) || ApiHttpRequestUtil.MESSAGE_CHANNEL_EXISTS.equals(jsonObject.getString("message")))) {          //HTTP返回成功
                JSONObject data = jsonObject.getJSONObject("data");
                dolby_ch = data.getString("ch");
                url = data.getString("hcdnlive");
                delayS = data.getIntValue("delay_s");
                delayE = data.getIntValue("delay_e");
            } else {        //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }

            LiveStream liveStream = new LiveStream();
            liveStream.setFatherId(fatherId);
            liveStream.setStreamName(streamName);
            liveStream.setIsDefault(false);
            liveStream.setUuid(UUID.randomUUID().toString());
            liveStream.setUrl(url);
            liveStream.setDolby_ch(dolby_ch);
            liveStream.setDelayE(delayE);
            liveStream.setDelayS(delayS);
            liveStream.setFormatType(LiveStream.FORMATTYPE_DOLBY);
            liveStream.setStatus(0);
            liveStreamService.save(liveStream);
            code = Constants.CODE_SUC;
            return code;
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][createDolby][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String startDolby(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][startDolby][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);

            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl()) && StringUtils.isNotEmpty(liveStream.getDolby_ch())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 启动dolby流
                JSONObject jsonObject = LiveStreamManager.startDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {         //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_START);
                    liveStreamService.edit(liveStream);

                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    if (liveChannelStream.getIsEnable()) {
                        // 写奇普
                        Long qipuId = channelService.getQipuId(fatherId);
                        //  Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if(qipuId > 0){
                            //  if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);

                            qipuManager.addLiveStreamToQipu(qipuId, liveStream);

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性hasStream\isSync
//                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
//                            channelBase.setHasStream(1);
//                            channelBase.setIsSync(1);
//                            channelService.saveBase(channelBase);
                            channelService.sqlNotifyHasStream(fatherId);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {        //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        channelService.sqlNotifyHasStream(fatherId);
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][startDolby][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String stopDolby(long fatherId, String streamName, boolean isQipuOperating) throws TException {
        logger.info("[LiveStreamWebServiceImpl][stopDolby][Params:fatherId={},streamName={},isQipuOperating={}]",
                new Object[]{fatherId, streamName, isQipuOperating});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);

            // 直播流未启动，无法停止
            if (null == liveStream || liveStream.getStatus() == 0 || liveStream.getStatus() == 2) {
                code = Constants.CODE_ERROR_STREAM_STATUS_STOP;
                return code;
            }

            // 检查频道当前是否有节目正在直播
            if (!checkNotHavingCurrentProgram(fatherId)) {
                code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
                return code;
            }

            if (StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
                // 停止dolby流
                JSONObject jsonObject = LiveStreamManager.stopDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_STOP);
                    liveStreamService.edit(liveStream);

                    if (liveChannelStream.getIsEnable() && isQipuOperating) {
                        // 写奇普
                        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                        Long qipuId = channelService.getQipuId(fatherId);
                        //        Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0){
                            //        if (qipuId > 0 && oldQipuId > 0) {       //奇普ID存在
//                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStreamHcdn.getUuid());

                            //频道FLV流为默认时，删除DefaultLiveStream
//                            if (liveStream.getIsDefault()) {
//                                qipuManager.setDefaultLiveStreamToQipu(qipuId, null);
//                            }

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性isSync
                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
                            channelBase.setIsSync(1);
                            channelService.saveBase(channelBase);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {                //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        // 不写奇普
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {                    //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                        //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][stopDolby][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String deleteDolby(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][deleteDolby][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);
            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl()) && StringUtils.isNotEmpty(liveStream.getDolby_ch())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 检查频道当前是否有节目正在直播
//                if (!checkNotHavingCurrentProgram(fatherId)) {
//                    code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
//                    return code;
//                }

                // 停止Flv流
                JSONObject jsonObject = LiveStreamManager.deleteDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    // 删除数据
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);

                    // 删奇普
                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    Long qipuId = channelService.getQipuId(fatherId);
                    // Long oldQipuId = channelService.getOldQipuId(fatherId);
                    if (qipuId > 0){
                        // if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                        qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());

                        //老奇普
//                        LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
//                        List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(fatherId, true);
//                        liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                        //设置频道属性isSync
                        ChannelBase channelBase = channelService.getChannelBase(fatherId);
                        channelBase.setIsSync(1);
                        channelService.saveBase(channelBase);
                        code = Constants.CODE_SUC;
                        return code;
                    } else {        //奇普ID不存在
                        code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                        return code;
                    }

                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][deleteDolby][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String restartDolby(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][restartDolby][fatherId={}][streamName={}]",
                fatherId, streamName);
        try {
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = service.get(fatherId, streamName, LiveStream.FORMATTYPE_DOLBY);
            LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

            JSONObject flvResult = LiveStreamManager.restartDolby(liveStream.getDolby_ch(), liveChannelStream.getDolbyStreamUrl(), liveChannelStream.getStreamApiVersion(),
                    liveChannelStream.getDolbyStreamUrls());
            if (null != flvResult && "1".equals(flvResult.getString("status"))) {
                return Constants.CODE_SUC;
            } else {
                return Constants.CODE_ERROR;
            }
        } catch (Exception e) {
            logger.info("[LiveStreamWebServiceImpl][restartDolby][fatherId=" + fatherId + "][streamName=" + streamName + "][exception={}]", e);
            return Constants.CODE_ERROR;
        }
    }

    @Override
    public String createNewTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][createNewTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        int sliceDelay = 0;
        int userCount = 0;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream _liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            if (_liveStream != null) {  //扩展流数据已存在
                code = Constants.CODE_ERROR_STREAMNAME_EXIST;
                return code;
            }
            LiveChannelStreamService liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream _liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
            if (_liveChannelStream == null) {     //频道码流数据不存在
                code = Constants.CODE_ERROR_LIVECHANNELSTREAM_NOT_EXIST;
                return code;
            } else {
                ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                ChannelBase channelBase = channelService.getChannelBase(fatherId);
                if (channelBase.getLiveType() != 2) {   //不为临时直播
                    if (_liveChannelStream.getStatus() != _liveChannelStream.STATUS_ACTIVED) {
                        code = Constants.CODE_WARNING_LIVECHANNELSTREAM_STATUS;
                        return code;
                    }
                } else {
                    sliceDelay = channelBase.getSliceDelay();
                }
                userCount = channelBase.getUserCount();
            }

            // 创建NewTS流 (newTs 和 dolby 使用相同的cutter接口)
            JSONObject jsonObject = LiveStreamManager.createDolby(_liveChannelStream.getStreamAddress(), _liveChannelStream.getStreamName(),
                    _liveChannelStream.getCutterIdTs() + "", sliceDelay, userCount,
                    LiveChannelStream.STREAM_TYPE_RESOLUTION_MAP.get(_liveChannelStream.getStreamType()), _liveChannelStream.getStreamApiVersion(),
                    _liveChannelStream.getStreamUrls());
            String url = null;
            int delayS = 0;
            int delayE = 0;
            String ts_ch = "";
            if (jsonObject != null && ("1".equals(jsonObject.getString("status")) || ApiHttpRequestUtil.MESSAGE_CHANNEL_EXISTS.equals(jsonObject.getString("message")))) {          //HTTP返回成功
                JSONObject data = jsonObject.getJSONObject("data");
                ts_ch = data.getString("ch");
                url = data.getString("hcdnlive");
                delayS = data.getIntValue("delay_s");
                delayE = data.getIntValue("delay_e");
            } else {        //HTTP返回失败
                code = Constants.CODE_ERROR_HTTP_RESULT;
                return code;
            }

            LiveStream liveStream = new LiveStream();
            liveStream.setFatherId(fatherId);
            liveStream.setStreamName(streamName);
            liveStream.setIsDefault(false);
            liveStream.setUuid(UUID.randomUUID().toString());
            liveStream.setUrl(url);
            liveStream.setDolby_ch(ts_ch);
            liveStream.setDelayE(delayE);
            liveStream.setDelayS(delayS);
            liveStream.setFormatType(LiveStream.FORMATTYPE_TS);
            liveStream.setStatus(0);
            liveStreamService.save(liveStream);
            code = Constants.CODE_SUC;
            return code;
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][createNewTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }    }

    @Override
    public String startNewTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][startNewTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);

            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl()) && StringUtils.isNotEmpty(liveStream.getDolby_ch())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 启动newTs流 (newTs 和 dolby 使用相同的cutter接口)
                JSONObject jsonObject = LiveStreamManager.startDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {         //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_START);
                    liveStreamService.edit(liveStream);

                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    if (liveChannelStream.getIsEnable()) {
                        // 写奇普
                        Long qipuId = channelService.getQipuId(fatherId);
                        //  Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if(qipuId > 0){
                            //  if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);

                            qipuManager.addLiveStreamToQipu(qipuId, liveStream);

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性hasStream\isSync
//                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
//                            channelBase.setHasStream(1);
//                            channelBase.setIsSync(1);
//                            channelService.saveBase(channelBase);
                            channelService.sqlNotifyHasStream(fatherId);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {        //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        channelService.sqlNotifyHasStream(fatherId);
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][startNewTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String stopNewTs(long fatherId, String streamName, boolean isQipuOperating) throws TException {
        logger.info("[LiveStreamWebServiceImpl][stopNewTs][Params:fatherId={},streamName={},isQipuOperating={}]",
                new Object[]{fatherId, streamName, isQipuOperating});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);

            // 直播流未启动，无法停止
            if (null == liveStream || liveStream.getStatus() == 0 || liveStream.getStatus() == 2) {
                code = Constants.CODE_ERROR_STREAM_STATUS_STOP;
                return code;
            }

            // 检查频道当前是否有节目正在直播
            if (!checkNotHavingCurrentProgram(fatherId)) {
                code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
                return code;
            }

            if (StringUtils.isNotEmpty(liveStream.getUrl())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);
                // 停止newTs流 (newTs 和 dolby 使用相同的cutter接口)
                JSONObject jsonObject = LiveStreamManager.stopDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    //修改数据
                    liveStream.setStatus(LiveStream.STATUS_STOP);
                    liveStreamService.edit(liveStream);

                    if (liveChannelStream.getIsEnable() && isQipuOperating) {
                        // 写奇普
                        ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                        Long qipuId = channelService.getQipuId(fatherId);
                        //        Long oldQipuId = channelService.getOldQipuId(fatherId);
                        if (qipuId > 0){
                            //        if (qipuId > 0 && oldQipuId > 0) {       //奇普ID存在
//                            QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());
//                            qipuManager.delLiveStreamToQipu(qipuId, liveStreamHcdn.getUuid());

                            //频道FLV流为默认时，删除DefaultLiveStream
//                            if (liveStream.getIsDefault()) {
//                                qipuManager.setDefaultLiveStreamToQipu(qipuId, null);
//                            }

                            //老奇普
//                            List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(liveChannelStream.getFatherId(), true);
//                            liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                            //设置频道属性isSync
                            ChannelBase channelBase = channelService.getChannelBase(fatherId);
                            channelBase.setIsSync(1);
                            channelService.saveBase(channelBase);
                            code = Constants.CODE_SUC;
                            return code;
                        } else {                //奇普ID不存在
                            code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                            return code;
                        }
                    } else {
                        // 不写奇普
                        code = Constants.CODE_SUC;
                        return code;
                    }
                } else {                    //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                        //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][stopNewTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String deleteNewTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][deleteNewTs][Params:fatherId={},streamName={}]", new Object[]{fatherId, streamName});
        String code = null;
        try {
            // 参数验证
            if (fatherId <= 0 || StringUtils.isEmpty(streamName)) {
                code = Constants.CODE_ERROR_PARAM;
                return code;
            }
            LiveStreamServiceImpl liveStreamService = (LiveStreamServiceImpl) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = liveStreamService.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            if (liveStream != null && StringUtils.isNotEmpty(liveStream.getUrl()) && StringUtils.isNotEmpty(liveStream.getDolby_ch())) {        //流已存在且URL不为空
                LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
                LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

                // 检查频道当前是否有节目正在直播
//                if (!checkNotHavingCurrentProgram(fatherId)) {
//                    code = Constants.CODE_ERROR_HAVING_CURRENT_PROGRAM;
//                    return code;
//                }

                // 停止Flv流
                JSONObject jsonObject = LiveStreamManager.deleteDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamApiVersion());
                if (jsonObject != null && "1".equals(jsonObject.getString("status"))) {      //HTTP返回成功
                    // 删除数据
                    liveStreamService.delete(fatherId, streamName, LiveStream.FORMATTYPE_TS);

                    // 删奇普
                    ChannelServiceImpl channelService = (ChannelServiceImpl) ApplicationContextUtil.getBean(ChannelServiceImpl.class);
                    Long qipuId = channelService.getQipuId(fatherId);
                    // Long oldQipuId = channelService.getOldQipuId(fatherId);
                    if (qipuId > 0){
                        // if (qipuId > 0 && oldQipuId > 0) {           //奇普ID存在
                        QipuManager qipuManager = (QipuManager) ApplicationContextUtil.getBean(QipuManager.class);
                        qipuManager.delLiveStreamToQipu(qipuId, liveStream.getUuid());

                        //老奇普
//                        LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
//                        List<LiveChannelStream> liveChannelStreams = liveChannelStreamService.getByIsEnable(fatherId, true);
//                        liveStreamService.writeToTvQipu(fatherId, oldQipuId, liveChannelStreams);

                        //设置频道属性isSync
                        ChannelBase channelBase = channelService.getChannelBase(fatherId);
                        channelBase.setIsSync(1);
                        channelService.saveBase(channelBase);
                        code = Constants.CODE_SUC;
                        return code;
                    } else {        //奇普ID不存在
                        code = Constants.CODE_ERROR_QIPUID_NOT_EXIST;
                        return code;
                    }

                } else {            //HTTP返回失败
                    code = Constants.CODE_ERROR_HTTP_RESULT;
                    return code;
                }
            } else {                //流不存在或URL为空
                code = Constants.CODE_ERROR_LIVESTREAM_NOT_EXIST;
                return code;
            }
        } catch (Exception e) {
            logger.error("exception={}", e);
            return Constants.CODE_ERROR;
        } finally {
            logger.info("[LiveStreamWebServiceImpl][deleteNewTs][End][Return:code={},codeValue={}]", new Object[]{code, Constants.getCode(code)});
        }
    }

    @Override
    public String restartNewTs(long fatherId, String streamName) throws TException {
        logger.info("[LiveStreamWebServiceImpl][restartNewTs][fatherId={}][streamName={}]",
                fatherId, streamName);
        try {
            LiveStreamService service = (LiveStreamService) ApplicationContextUtil.getBean(LiveStreamService.class);
            LiveStream liveStream = service.get(fatherId, streamName, LiveStream.FORMATTYPE_TS);
            LiveChannelStreamServiceImpl liveChannelStreamService = (LiveChannelStreamServiceImpl) ApplicationContextUtil.getBean(LiveChannelStreamServiceImpl.class);
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(fatherId, streamName);

            JSONObject result = LiveStreamManager.restartDolby(liveStream.getDolby_ch(), liveChannelStream.getStreamAddress(), liveChannelStream.getStreamApiVersion(),
                    liveChannelStream.getStreamUrls());
            if (null != result && "1".equals(result.getString("status"))) {
                return Constants.CODE_SUC;
            } else {
                return Constants.CODE_ERROR;
            }
        } catch (Exception e) {
            logger.info("[LiveStreamWebServiceImpl][restartNewTs][fatherId=" + fatherId + "][streamName=" + streamName + "][exception={}]", e);
            return Constants.CODE_ERROR;
        }
    }


}
